Unit DamageCalc;

{$mode objfpc}{$H+}

Interface

Uses
  Crt,
  MenuDraw,
  Initializer,
  Enemies,
  XpTable,
  Abilities,
  Items,
  DefaultClasses,
  EnA;

Var
  PreDamage : Integer;
  CombatAction,
  ItemChoice : Char;

Procedure BattleShower(ClassType, HeroName : String; Var Health, Rage, EHP, Mana, Energy : Integer);
Procedure HeroAttackDamage(ClassType : String; Strength, Wisdom, Agility : Integer);
Function HeroAttack(Var PreDamage : Integer) : Integer;
Procedure Damager(Var PreDamage, EHP : Integer; CombatAction : Char; HeroName : String; Var Rage, Energy : Integer; Var Health : Integer);
Procedure CombatMenu(ClassType : String; Rage, Mana, Energy : Integer; HeroName : String; Var Health, EHP : Integer);
Procedure Fight(Var Hit : Boolean; Var EHP, Health : Integer; HeroName : String; Var Gold : Integer; Var Mana : Integer);

Implementation

//Basic battle hud.
//This displays the health and class resource
//whilst there is a battle going on.
//As well as showing any status ailments.
Procedure BattleShower(ClassType, HeroName : String; Var Health, Rage, EHP, Mana, Energy : Integer);
 Begin
   Clrscr;
   If ClassType = 'Warrior' then
     Begin
     GotoXY(6,1);
       Write(HeroName,' Health: ',Health,'     ');
       Write('Rage: ',Rage);
       If (Ailment1 <> '') or (Ailment2 <> '') then
         Writeln(' ',Ailment1,' ',Ailment2);
     Writeln;
     GotoXY(6,2);
       Writeln('Enemy Health: ',EHP);
     Writeln;
     end;

   If ClassType = 'Mage' then
     Begin
     GotoXY(6,1);
       Write(HeroName,' Health: ',Health);
     GotoXY(25,1);
       Write(' Mana: ',Mana);
     If (Ailment1 <> '') or (Ailment2 <> '') then
         Writeln(' ',Ailment1,' ',Ailment2);
     Writeln;
     GotoXY(6,2);
       Writeln('Enemy Health: ',EHP);
     Writeln;
     end;

   If ClassType = 'Archer' then
     Begin
     GotoXY(6,1);
       Write(HeroName,' Health: ',Health,'     ');
       Write('Energy: ',Energy);
     If (Ailment1 <> '') or (Ailment2 <> '') then
         Writeln(' ',Ailment1,' ',Ailment2);
     Writeln;
     GotoXY(6,2);
       Writeln('Enemy Health: ',EHP);
     Writeln;
     end;
   Writeln;
 end;

//This subroutine calculates the damage as if the player
//used a generic melee attack.
//The damage is based on the player's base stat - which varies
//per class.
//And then a random value between 15 and 45 is added to the
//damage.
//This final value is assigned to the 'PreDamage' variable
//to be taken into a further down subroutine for the final
//damage dealing procedure.
Procedure HeroAttackDamage(ClassType : String; Strength, Wisdom, Agility : Integer);
Var
  Damage : Integer;

 Begin
  Randomize;

  If ClassType = 'Warrior' then
    Begin
      Damage := Strength * 7;
      Damage := Damage + Random(30 + 15);
      PreDamage := Damage;
  end;

  If ClassType = 'Mage' then
    Begin
      Damage := Wisdom * 4;
      Damage := Damage + Random(30 + 15);
      PreDamage := Damage;
  end;

  If ClassType = 'Archer' then
    Begin
      Damage := Agility * 6;
      Damage := Damage + Random(30 + 15);
      PreDamage := Damage;
  end;

 end;

//This procedure chooses which ability list to display
//for the player when the second option is chosen
//from the 'BattleMenu'.
Procedure AbilityType(ClassType : String);
 Begin
   If ClassType = 'Warrior' then
     WarriorList(Level, Rage);

   If ClassType = 'Mage' then
     MageList(Level, Mana);

   If ClassType = 'Archer' then
     ArcherList(Level, Energy);

 end;

//Displays the ability menu for the player's class.
//This subroutine is called  when the user presses 2(#50) from
//the battle menu.
//The PreDamage is calculated when the user selects which ability to
//use from the appropriate 'Class'List from above.
//The PreDamage is then taken into the following subroutine
//and assigned to then be taken and ready to use in the
//procesure that calulates and deals damage.
Procedure AbilityList(Var PreDamage : Integer);
 Begin
   AbilityType(ClassType);
   PreDamage := AbilityDamage;
 end;

//This subroutie takes the players damage
//caluated from either an ability or melee attack
//that is defined in the variable 'PreDamage'.
//This subroutine then assigns the value of PreDamage
//to the variable 'HeroAttack' which is used to
//calulate the player's damage in the 'Damager'
//Procedure.
Function HeroAttack(Var PreDamage : Integer) : Integer;
 Begin
  HeroAttack := PreDamage;
 end;

//This subroutine calculates the damage for used when it is
//called in the procedure 'Fight'.
//This Procedure performs multiple amounts of
//instructions in a certain order;
//-assigns the base damage for following calulation
//-deals the player's damage
//-deals enemy's damage
//-replenishes warrior and archer class resource depending on
//what damage was dealt
Procedure Damager(Var PreDamage, EHP : Integer; CombatAction : Char; HeroName : String; Var Rage, Energy : Integer; Var Health : Integer);
Var
  HeroDamage, EnemyDamage : Integer;

 Begin
   //Damage assignment
   HeroAttack(PreDamage);
   HeroDamage := HeroAttack(PreDamage);
   EnemyDamage := EnemyAttack(CombatAction, ESTR);

   //Player's Damage
   If (CombatAction = #49) or (CombatAction = #50) then
     Begin
       EHP := EHP - (HeroDamage + DamageBoost);
       Writeln(HeroName,' deals ',HeroDamage,' to the Enemy!');
       Writeln('Leaving the enemy with ',EHP);

       If (ClassType = 'Warrior') and (Rage <> 100) then
         Rage := Rage + (HeroDamage div 10);

       If (ClassType = 'Archer') and (Energy <> 100) then
         Energy := Energy + (HeroDamage div 10);
     end;

   Writeln;

   //Enemy's Damage
   If EnemyDamage < 1 then
     Begin
       Writeln('Enemy used poison attack on you!, You''re poisoned!')
     end else
       Begin
         Health := Health - EnemyDamage;
         If CombatAction = #51 then
           Writeln('Your block reduced the enemy attack to ',EnemyDamage)
         else
           Writeln('Enemy attacks you for ',EnemyDamage);
         Writeln('Leaving you with ',Health);
       end;


   //Following lines are fight replinshers for the warriror
   //and archer class resources.
   If (ClassType = 'Warrior') and (Rage <> 100) then
     Rage := Rage + (EnemyDamage div 10);

   If (ClassType = 'Archer') and (Energy <> 100) then
     Energy := Energy + (EnemyDamage div 5);

   If Rage > 100 then
     Rage := 100;

   If Energy > 100 then
     Energy := 100;
 end;

//Simple battle menu.
Procedure CombatMenu(ClassType : String; Rage, Mana, Energy : Integer; HeroName : String; Var Health, EHP : Integer);
 Begin
   Repeat
     BattleShower(ClassType, HeroName, Health, Rage, EHP, Mana, Energy);
     GotoXY(1,3);
     Writeln('Combat Menu;');
     Writeln('1: Attack');
     Writeln('2: Abilities');
     Writeln('3: Block');
     Writeln('4: Item');
     Writeln;


     CombatAction := ReadKey;
     Case CombatAction of
       #49 : HeroAttackDamage(ClassType, Strength, Wisdom, Agility);            //Deals Damage
       #50 : AbilityList(PreDamage);                                            //Abilities
       #51 : ;                                                                  //Block
       #52 : Begin                                                              //Item
               If UsedItem = False then //So the Player can only use 1 item per round.
                 Begin
                   Battle_ItemList
                 end
                 else
                   Begin
                     Writeln('You''ve already used an item this round');
                     Attention;
                   end;
             end;

     end;
   Clrscr;
   Until (CombatAction = #49) or
         ((CombatAction = #50) and (Hit)) or
         (CombatAction = #51);
 end;


//The fight procedure is where the health gets finally modified
//before repeating a set or procedures until either player or
//enemy dies, and then awards after battle rewards.
Procedure Fight(Var Hit : Boolean; Var EHP, Health : Integer; HeroName : String; Var Gold : Integer; Var Mana : Integer);
 Begin
   Clrscr;
   EnemySpawn(Level, EHP, ESTR, EXPReward);
   Repeat
     ItemStatBoostReset;
     Hit := False;
     UsedItem := False;
     CombatMenu(ClassType, Rage, Mana, Energy, HeroName, Health, EHP);
     PreAilmentEffects;
     Damager(PreDamage, EHP, CombatAction, HeroName, Rage, Energy, Health);

     Writeln;
     PostAilmentEffects(Health);
     Attention;
   Until (EHP <= 0) or (Health <= 0);

   If Health <= 0 then
     Writeln('You died - Returning to INN');

   If EHP <= 0 then
     Begin
       Writeln('Fight over, you won');
       Gold := Gold + GoldReward;
       Writeln('You earned ',GoldReward,' Gold');
       XpGiver(EXP, EXPReward);
       Writeln('You earned ',EXPReward+XpBoost,'XP from killing that enemy');
       Leveller(Level, EXP, ClassType, Hp, Strength, Wisdom, MP, Agility);

     end;

   XpBoost := 0;

   Attention;

 end;

end.
